<template>
  <div
    :class="dragFlag ? 'dragm' : 'app-container'"
    @dragover.prevent="handleDragOver"
    @drop.stop.prevent="handleFileDrop"
  >
    <span v-show="dragFlag" class="textdrag">{{
      $t("coursematerial.Dateienziehen")
    }}</span>
    <el-row :gutter="4">
      <el-col :xs="24">
        <el-card shadow="never">
          <template #header>
            <div class="flex flex-star">
              <el-upload
                ref="upload"
                v-hasPerm="['courseinfo:coursematerial:addfile']"
                :show-file-list="false"
                :auto-upload="false"
                :on-change="handleChange"
              >
                <el-button type="success">
                  <svg-icon
                    :icon-class="'folder-upload'"
                    style="margin-right: 5px; font-size: 18px"
                  />{{ $t("coursematerial.Dateienhochladen") }}</el-button
                >
              </el-upload>

              <el-button
                v-hasPerm="['courseinfo:coursematerial:edit']"
                v-throttle="addFolder"
                style="margin-left: 10px"
                type="warning"
                :disabled="addFlag"
              >
                <svg-icon
                  :icon-class="'fd_add'"
                  style="margin-right: 5px; font-size: 18px"
                />{{ $t("coursematerial.NeuerOrdner") }}</el-button
              >
              <div style="position: absolute; top: 18px; right: 15px">
                <el-button
                  v-hasPerm="['courseinfo:coursematerial:delete']"
                  v-throttle="handleDelete"
                  type=""
                  :disabled="ids.length === 0"
                  plain
                  style="color: var(--el-color-danger)"
                >
                  <svg-icon
                    :icon-class="'piliangshanchu'"
                    style="margin-right: 5px; font-size: 20px"
                  />{{ $t("coursematerial.Stapellöschung") }}</el-button
                >

                <el-button
                  v-hasPerm="['courseinfo:coursematerial:download']"
                  v-throttle="handleDownload"
                  type=""
                  :disabled="ids.length === 0"
                  plain
                  style="color: var(--el-color-primary)"
                >
                  <svg-icon
                    :icon-class="'piliangxiazai'"
                    style="margin-right: 5px; font-size: 26px"
                  />{{ $t("coursematerial.BatchDownload") }}</el-button
                >
              </div>
            </div>
          </template>

          <el-breadcrumb
            class="flex items-center"
            style="margin-left: 14px; margin-top: -5px; margin-bottom: 5px"
            :separator-icon="ArrowRight"
          >
            <span
              v-if="breadcrumbs.length > 1"
              v-throttle="goBack"
              style="color: var(--el-menu-active-color); cursor: pointer"
            >
              {{ $t("coursematerial.Ebene") }} |&nbsp;&nbsp;
            </span>
            <transition-group name="breadcrumb">
              <el-breadcrumb-item
                v-for="(item, index) in breadcrumbs"
                :key="index"
              >
                <span
                  v-if="index === breadcrumbs.length - 1"
                  :class="
                    breadcrumbs.length - 1 !== 0
                      ? 'text-[var(--el-disabled-text-color)]'
                      : 'title'
                  "
                  >{{
                    index === 0 ? $t("coursematerial.AlleDateien") : item.name
                  }}</span
                >
                <a
                  v-if="index !== breadcrumbs.length - 1"
                  v-throttle="() => handleLink(item)"
                  style="font-weight: normal"
                >
                  {{
                    index === 0 ? $t("coursematerial.AlleDateien") : item.name
                  }}
                </a>
              </el-breadcrumb-item>
            </transition-group>
          </el-breadcrumb>

          <el-table
            ref="tableRef"
            v-loading="loading"
            :empty-text="$t('coursematerial.DerzeitDateiinformationen')"
            :max-height="calculatedValue"
            :data="fileList"
            :highlight-current-row="true"
            @cell-mouse-enter="handleMouseEnter"
            @cell-mouse-leave="handleMouseLeave"
            @selection-change="handleSelectionChange"
          >
            <!-- 表格列 -->
            <template #default>
              <el-table-column type="selection" width="40" align="left">
                <template #default="scope">
                  <div
                    v-if="
                      scope.row.id * 10 + scope.row.type === renameFileId &&
                      renameView
                    "
                  />
                </template>
              </el-table-column>
              <el-table-column v-if="false" prop="id" />
              <el-table-column
                :label="$t('coursematerial.Dateiname')"
                align="left"
                prop="name"
              >
                <template #default="scope">
                  <div
                    style="
                      display: flex;
                      width: 100%;
                      justify-content: space-between;
                    "
                    :class="
                      scope.row.id * 10 + scope.row.type === hoverRow
                        ? 'highlight'
                        : 'common'
                    "
                    @click="clickRow(scope.row)"
                  >
                    <div style="display: flex">
                      <svg-icon
                        :icon-class="
                          scope.row.type === 1
                            ? 'folder'
                            : scope.row.name.split('.').at(-1)
                        "
                        style="
                          font-size: 28px;
                          margin-right: 5px;
                          vertical-align: middle;
                        "
                      />
                      <span
                        v-if="
                          scope.row.id * 10 + scope.row.type !== renameFileId
                        "
                        class="middlea file-name"
                        style="vertical-align: middle"
                        @click.stop="fileClick(scope.row)"
                        >{{ scope.row.name }}</span
                      >
                      <div
                        v-if="
                          scope.row.id * 10 + scope.row.type === renameFileId &&
                          renameView
                        "
                        style="display: flex"
                      >
                        <el-input
                          v-model="fileEditForm.name"
                          :placeholder="
                            $t('coursematerial.BitteOrdnernamenein')
                          "
                          style="margin-left: 0px"
                        />
                        <svg-icon
                          :icon-class="'fd_ok'"
                          style="margin-left: 14px; font-size: 36px"
                          class="icon_class"
                          @click.stop="renameOk(scope.row.type)"
                        />
                        <svg-icon
                          :icon-class="'fd_cancel'"
                          style="margin-left: 6px; font-size: 36px"
                          class="icon_class"
                          @click.stop="renameCancel"
                        />
                      </div>
                    </div>
                    <div
                      v-if="
                        scope.row.id * 10 + scope.row.type === hoverRow &&
                        scope.row.id * 10 + scope.row.type !== renameFileId
                      "
                      style="
                        white-space: nowrap;
                        z-index: 10;
                        text-overflow: ellipsis;
                      "
                    >
                      <el-tooltip
                        v-if="scope.row.type !== 1"
                        :content="$t('coursematerial.Prüfung')"
                        placement="bottom"
                        effect="light"
                      >
                        <svg-icon
                          :icon-class="'fd_view'"
                          class="operation_class"
                          style="
                            font-size: 18px;
                            line-height: 18px;
                            vertical-align: middle;
                          "
                          @click.stop="fileClick(scope.row)"
                        />
                      </el-tooltip>

                      <el-tooltip
                        v-hasPerm="['courseinfo:coursematerial:delete']"
                        :content="$t('coursematerial.löschen')"
                        placement="bottom"
                        effect="light"
                      >
                        <svg-icon
                          :icon-class="'fd_delete'"
                          style="
                            margin-left: 14px;
                            font-size: 18px;
                            line-height: 18px;
                            vertical-align: middle;
                          "
                          class="operation_class"
                          @click.stop="fileDelete(scope.row)"
                        />
                      </el-tooltip>

                      <el-tooltip
                        v-hasPerm="['courseinfo:coursematerial:download']"
                        :content="$t('coursematerial.Download')"
                        placement="bottom"
                        effect="light"
                      >
                        <svg-icon
                          v-throttle="() => handleDownload(scope.row)"
                          :icon-class="'fd_download'"
                          style="
                            margin-left: 14px;
                            font-size: 18px;
                            line-height: 18px;
                            vertical-align: middle;
                          "
                          class="operation_class"
                        />
                      </el-tooltip>

                      <el-tooltip
                        v-hasPerm="['courseinfo:coursematerial:edit']"
                        :content="$t('coursematerial.umbenennen')"
                        placement="bottom"
                        effect="light"
                      >
                        <svg-icon
                          :icon-class="'fd_rename'"
                          style="
                            margin-left: 14px;
                            font-size: 18px;
                            line-height: 18px;
                            vertical-align: middle;
                          "
                          class="operation_class"
                          @click.stop="renameFile(scope.row)"
                        />
                      </el-tooltip>
                    </div>
                  </div>
                </template>
              </el-table-column>
              <el-table-column
                :label="$t('coursematerial.Änderungszeit')"
                align="left"
                prop="updateTime"
                width="300"
              />

              <el-table-column
                :label="$t('coursematerial.Größe')"
                align="left"
                prop="size"
                width="200"
              />
            </template>
          </el-table>
        </el-card>
      </el-col>
    </el-row>
    <el-dialog
      v-model="imgVisible"
      append-to-body
      :title="$t('coursematerial.Vorschau')"
      style="width: 60%"
      @close="false"
    >
      <iframe :src="previewURL" style="width: 100%; height: 600px"></iframe>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
defineOptions({
  name: "Coursematerial",
  inheritAttrs: false,
});
import SparkMD5 from "spark-md5";
import { ArrowRight } from "@element-plus/icons-vue";
import { FileTableInfo } from "@/api/file/types";
import { FileEditForm, FileTableForm } from "@/api/folder/types";
import {
  deleteCourseFile,
  deleteCourseFiles,
  getFiles,
  saveFile,
  uploadCourseAnnex,
} from "@/api/folder";
import { formatDate } from "@/utils/formatTime";
import { formatbytes } from "@/utils/byte";
import { downloadFilesAsync, downloadBlob } from "@/utils/file";
import { useCourseStore } from "@/store/modules/course";
import { useAppStore } from "@/store/modules/app";
import { verifyFile } from "@/utils/file";
import { downloadFile, downloadFiles } from "@/api/file";
import { useWindowSize } from "@vueuse/core";
const { height } = useWindowSize();
const calculatedValue = ref(0);

const disabledvalue = ref(false);
const courseStore = useCourseStore();
const courseId = ref();
const appStore = useAppStore();
const timer = ref<null | number>(null); // 防抖
type BreadType = {
  id?: number | null;
  name?: string;
};
const loading = ref(false);
const addFlag = ref(false);
const fileList = ref<FileTableInfo[]>([]);
const ids = ref<FileTableForm[]>([]);
// 当前悬停的行
const hoverRow = ref(null);
const renameView = ref(false);
const dragFlag = ref(false);
const renameFileId = ref<number | null>(-1);
// 当前选中的行
const selectedRow = ref(null);
const fileEditForm = reactive<FileEditForm>({});
const folderId = ref<number | null>(null);
const previewURL = ref("");
const imgVisible = ref(false);
const tableRef = ref(ElTable);
const breadcrumbs = ref<BreadType[]>([
  {
    id: null,
    name: "全部文件",
  },
]);

watch(
  () => height.value,
  (newValue: any, oldValue: any) => {
    // const windowHeight = window.innerHeight;
    calculatedValue.value = newValue - 280;
  },
  { immediate: true }
);

// 行checkbox
function handleSelectionChange(selection: any) {
  ids.value = selection.map((item: any) => {
    return { id: item.id, type: item.type };
  });
}
// 监听 mouseenter 事件
function handleMouseEnter(row: any, column: any, cell: any, event: any) {
  hoverRow.value = row.id * 10 + row.type;
}
// 监听 拖拽 事件
function handleDragOver(e: any) {
  e.stopPropagation();
  e.preventDefault();
  dragFlag.value = true;
  // dragover+防抖代替dragenter和dragleave
  if (timer.value !== null) {
    clearTimeout(timer.value);
  }
  timer.value = window.setTimeout(() => {
    dragFlag.value = false;
    timer.value = null;
  }, 100);
}
// 处理文件拖拽完成后的事件
const handleFileDrop = (e: any) => {
  e.preventDefault();
  dragFlag.value = false;
  loading.value = true;
  const files = e.dataTransfer.files;
  for (var i = 0; i < files.length; i++) {
    const reader = new FileReader();
    const spark = new SparkMD5.ArrayBuffer();
    const file = files[i];
    reader.readAsArrayBuffer(file);
    reader.onload = (e: any) => {
      spark.append(reader.result as ArrayBuffer);
      const md5 = spark.end();
      uploadCourseAnnex(
        file,
        md5,
        breadcrumbs.value[breadcrumbs.value.length - 1].id!,
        courseId.value
      )
        .then(() => {
          handleQuery();
        })
        .catch(() => {
          const index = fileList.value.indexOf(file);
          fileList.value.splice(index, 1);
          ElMessage.error("文件上传失败");
        })
        .finally(() => {
          loading.value = false;
        });
    };
  }
  ElMessage.success("文件上传成功");
};
// 监听 mouseleave 事件
function handleMouseLeave(row: any, column: any, cell: any, event: any) {
  hoverRow.value = null;
}
// 监听点击链接
function handleLink(item: any) {
  const array = ref<BreadType[]>([]);
  for (let i = 0; i < breadcrumbs.value.length - 1; i++) {
    array.value.push(breadcrumbs.value[i]);

    if (breadcrumbs.value[i].id === item.id) {
      break;
    }
  }
  breadcrumbs.value = array.value;
  const back = breadcrumbs.value[breadcrumbs.value.length - 1];
  folderId.value = back.id!;
  handleQuery();
}
function goBack() {
  breadcrumbs.value.pop();
  const back = breadcrumbs.value[breadcrumbs.value.length - 1];
  folderId.value = back.id!;
  handleQuery();
}
// 批量删除文件
function handleDelete() {
  if (ids.value.length === 0) {
    ElMessage.warning("请勾选删除项");
    return;
  }
  ElMessageBox.confirm("确认删除文件?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(function () {
    deleteCourseFiles(ids.value).then(() => {
      ElMessage.success("删除成功");
      handleQuery();
    });
  });
}
// 上传
function handleChange(file: any, fileList: any) {
  if (!verifyFile(file, fileList)) return;
  const reader = new FileReader();
  const spark = new SparkMD5.ArrayBuffer();
  reader.readAsArrayBuffer(file.raw);
  reader.onload = (e) => {
    spark.append(reader.result as ArrayBuffer);
    const md5 = spark.end();
    uploadCourseAnnex(
      file.raw,
      md5,
      breadcrumbs.value[breadcrumbs.value.length - 1].id!,
      courseId.value
    )
      .then((res) => {
        ElMessage.success("文件上传成功");
        handleQuery();
      })
      .catch(() => {
        const index = fileList.indexOf(file);
        fileList.splice(index, 1);
        ElMessage.error("文件上传失败");
      });
  };
}
// 监听 mouseleave 事件
function addFolder() {
  //disabledvalue.value = true
  addFlag.value = true;
  fileList.value.unshift({
    id: 0,
    name: "",
    updateTime: formatDate(new Date()),
    size: "-",
    type: 1,
  });
  fileEditForm.id = 0;
  renameFileId.value = 1;
  renameView.value = true;
  //disabledvalue.value = false
}
// 重命名
function renameFile(row: any) {
  renameCancel();
  fileEditForm.id = row.id;
  fileEditForm.name = row.name;
  renameFileId.value = row.id * 10 + row.type;
  renameView.value = true;
}
// 取消重命名
function renameCancel() {
  if (fileEditForm.id == 0) {
    fileList.value.shift();
  }

  renameView.value = false;
  addFlag.value = false;
  renameFileId.value = -1;
}
function clickRow(row: any) {
  if (row.id != null && !renameView.value)
    tableRef.value!.toggleRowSelection(row, undefined);
}
function renameOk(type: number) {
  if (fileEditForm.name?.trim() == "" || fileEditForm.name == null) {
    ElMessage.error("请正确填写文件名称");
    return;
  }
  fileEditForm.parentId = breadcrumbs.value[breadcrumbs.value.length - 1].id;
  fileEditForm.type = type;

  saveFile(fileEditForm, courseId.value).then(() => {
    ElMessage.success("文件修改成功");
    fileEditForm.id = null;
    fileEditForm.name = "";
    renameView.value = false;
    renameFileId.value = -1;
    handleQuery();
    addFlag.value = false;
  });
}
function fileClick(row: any) {
  if (row.type == 1) {
    folderId.value = row.id;
    breadcrumbs.value.push({
      id: row.id,
      name: row.name,
    });
    handleQuery();
  } else {
    const fileName = row.name.split(".");
    const fileExt = fileName.at(-1) ?? "";
    if (fileExt == "pdf") {
      previewURL.value = "http://oss.dachtech.info/" + row.path;
    } else {
      previewURL.value = row.url;
    }
    imgVisible.value = true;
  }
}
function fileDelete(row: any) {
  ElMessageBox.confirm("确认删除文件?", "警告", {
    confirmButtonText: "确定",
    cancelButtonText: "取消",
    type: "warning",
  }).then(function () {
    deleteCourseFile(row.id, row.type)
      .then(() => {
        ElMessage.success("删除文件成功");
      })
      .catch(() => {
        ElMessage.error("文件删除失败");
      })
      .finally(() => {
        handleQuery();
      });
  });
}
// 下载文件
function handleDownload(row?: any) {
  if (!row) {
    downloadFilesAsync(ids.value);
  } else {
    // 使用三元运算符，简化判断row类型的if-else语句
    (row.type === 2
      ? downloadFile(row.path, row.name)
      : downloadFiles(
          ref<FileTableForm[]>([{ id: row.id, type: row.type }]).value
        )
    ).then((response) => {
      downloadBlob(response);
    });
  }
}
// 查询
function handleQuery() {
  loading.value = true;
  getFiles(folderId.value, courseId.value)
    .then(({ data }) => {
      fileList.value = [];

      data.folderList.forEach((folderItem) => {
        const folder: FileTableInfo = {
          name: folderItem.folderName,
          id: folderItem.folderId,
          updateTime: folderItem.updateTime,
          size: "-",
          type: 1,
        };
        fileList.value.push(folder);
      });

      data.fileList.forEach((fileItem) => {
        const file: FileTableInfo = {
          name: fileItem.fileName,
          id: fileItem.fileId,
          updateTime: fileItem.updateTime,
          size: formatbytes(fileItem.size),
          path: fileItem.path,
          url: fileItem.fileUrl,
          type: 2,
          downloadUrl: fileItem.downloadUrl,
        };
        fileList.value.push(file);
      });
    })
    .finally(() => {
      loading.value = false;
    });
}

onMounted(() => {
  courseId.value = courseStore.courseId;
  handleQuery();
  appStore.sidebar.opened = false;
});
</script>

<style lang="scss" scoped>
.dragm {
  opacity: 0.5;
  background-color: #f1f1f1;
  border: dashed 5px skyblue;
}

.textdrag {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  font-size: 38px;
  z-index: 999;
}

.middlea {
  vertical-align: middle;
  display: table-cell;
  line-height: 28px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  -o-text-overflow: ellipsis;
}

.highlight {
  color: var(--el-menu-active-color);
  cursor: pointer;
}

.drop-zone {
  width: 300px;
  height: 200px;
  border: 2px dashed #ccc;
  display: flex;
  justify-content: center;
  align-items: center;
}

.icon_class {
  color: var(--el-menu-active-color);
}

.file-name {
  color: var(--text-black-color);
}

.file-name:hover {
  color: var(--el-menu-active-color);
}

.title {
  color: var(--text-black-color);
  font-weight: bold;
}
</style>
